package io.xxx.xbutler.core.callback;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hy.corecode.idgen.WFGIdGenerator;
import io.xxx.xbutler.data.RobotRoomMapper;
import io.xxx.xbutler.data.RoomMapper;
import io.xxx.xbutler.domain.Callback;
import io.xxx.xbutler.domain.RobotRoom;
import io.xxx.xbutler.domain.Room;
import io.xxx.xbutler.domain.RoomType;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * 群信息回调（兼容PC）
 * <p>
 * 群名称、群主转移（机器人被转移为群主）、群头像变化，当多个机器人在群内时，所有机器人群信息变动回调参照以下规则：
 * 1、非机器人群主把群主转移给为管理员的机器人时，每个机器人不论是否开群都会收到群信息变动回调（4001），每个机器人收到群管理员变动回调（4510，被设置为群主的机器人管理员取消）
 * 2、非机器人群主把群主转移给非管理员机器人时，每个机器人收到4001回调
 * 3、非机器人群主把群主转移给普通成员的管理员时，每个机器人都会收到群信息变动回调（4001） ，同时每个机器人会收到群管理员变动回调（4510，普通群成员的管理员被取消变成了群主）
 * 4、非机器人群主把群主转移给普通成员时，每个机器人会收到4001回调
 * 机器人群主转移群主时，无群信息回调（4001）
 * 5、群成员进退群时，群人数变化也会有4001回调通知商家；
 * PC协议无企业微信外部群相关字段，仅支持接收全量群数据，群变动无感知；
 *
 * <pre>
 * {
 *     "vcMerchantNo": "202309130012311",
 *     "vcRobotWxId": "wxid_em0xmsjed5w222",
 *     "vcRobotSerialNo": "758001B6E1E599533AC47887C4601AA0",
 *     "vcSerialNo": "20250113171957145076618269205",
 *     "nType": 4001,
 *     "nResult": 1,
 *     "vcResult": "SUCCESS",
 *     "nTimeStamp": 1736759997283,
 *     "Data": [
 *         {
 *             "vcChatRoomId": "16227922736@chatroom",
 *             "vcChatRoomSerialNo": "1BD96672F71AEB4C19E3261770501C81",
 *             "nUserCount": 270,
 *             "vcName": "小区生活超市",
 *             "vcBase64Name": "5bCP5Yy655Sf5rS76LaF5biC",
 *             "vcAdminWxId": "wxid_snx4fa5gwqil21",
 *             "vcAdminWxUserSerialNo": "3CF2C6B46300F72A395DB5E936E0A368",
 *             "nIsInContacts": 0,
 *             "nRobotInStatus": 0,
 *             "isOpenMessage": 10,
 *             "vcGroupNotice": "",
 *             "vcBase64Notice": "",
 *             "vcHeadImgUrl": "https://wx.qlogo.cn/mmcrhead/II9YXRiafk7hZibnic5t2VdoK75tKuicJWTRibTEM6zOqHTX7sQXsz8nQwhZevqFPO2p38iac8JqUcvRr53ics6wFM2a37qckkdMSGn/0",
 *             "ChatAdminType": 0,
 *             "IsEnterpriseChatroom": false,
 *             "is_top": false
 *         }
 *     ]
 * }
 * </pre>
 */
@Slf4j
@Component
public class _4001Handler implements CallbackHandler {

    @Resource
    private WFGIdGenerator idGenerator;

    @Resource
    private RoomMapper roomMapper;

    @Resource
    private RobotRoomMapper robotRoomMapper;

    @Override
    public String name() {
        return "群信息回调";
    }

    @Override
    public boolean supports(int type) {
        return type == 4001;
    }

    @Override
    public void handle(Callback callback) {
        JSONArray data = (JSONArray) callback.getData();

        LocalDateTime now = LocalDateTime.now();
        for (Object datum : data) {
            saveRobotRoom(callback, JSONObject.from(datum), now);
        }
    }

    public void saveRobotRoom(Callback callback, JSONObject data, LocalDateTime now) {
        String robotId = callback.getRobotId();
        String robotSerialNo = callback.getRobotSerialNo();
        Room room = buildRoom(data, now);
        LambdaQueryWrapper<Room> queryWrapper = new LambdaQueryWrapper<Room>()
                .eq(Room::getId, room.getId());
        boolean roomExists = roomMapper.exists(queryWrapper);
        if (roomExists) {
            roomMapper.updateById(room);
        } else {
            room.setCreatedTime(now);
            roomMapper.insert(room);
        }

        LambdaQueryWrapper<RobotRoom> robotRoomWrapper = new LambdaQueryWrapper<RobotRoom>()
                .eq(RobotRoom::getRobotId, robotId)
                .eq(RobotRoom::getRoomId, room.getId());
        boolean robotRoomExists = robotRoomMapper.exists(robotRoomWrapper);
        if (!robotRoomExists) {
            RobotRoom robotRoom = new RobotRoom()
                    .setId(idGenerator.next())
                    .setRobotId(robotId)
                    .setRobotSerialNo(robotSerialNo)
                    .setRoomId(room.getId())
                    .setRoomSerialNo(room.getSerialNo())
                    .setRoomName(data.getString("vcName"))
                    .setCreatedTime(now)
                    .setUpdatedTime(now);
            robotRoomMapper.insert(robotRoom);
        }
    }

    protected Room buildRoom(JSONObject data, LocalDateTime now) {
        return new Room()
                .setId(data.getString("vcChatRoomId"))
                .setSerialNo(data.getString("vcChatRoomSerialNo"))
                .setMemberCount(data.getInteger("nUserCount"))
                .setName(data.getString("vcName"))
                .setBase64Name(data.getString("vcBase64Name"))
                .setAvatar(data.getString("vcHeadImgUrl"))
                .setOwnerId(data.getString("vcAdminWxId"))
                .setOwnerSerialNo(data.getString("vcAdminWxUserSerialNo"))
                .setNotice(data.getString("vcGroupNotice"))
                .setBase64Notice(data.getString("vcBase64Notice"))
                .setType(RoomType.values()[data.getInteger("IsEnterpriseChatroom")])
                .setUpdatedTime(now);
    }
}
